import java.util.Collection; //for the hashtable
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.LinkedHashMap;
import java.util.Set;

import java.util.*; //for file writing
import java.io.*;

/* *********************************************************** *\
 FileMaker Class
 -Stores attribute/value pairs.
 -Writes syntax to .ics file.

 Global Vars
 -private event_attributes
 -private calendar_attributes

 Functions
 -FileMaker()           |   creates hashtables
 -set_attribute(key,value)  |   adds entry, overwrites existing entries, for event attrs
 -set_attribute(key,value,type) |   adds entry, specifically add event or calendar attrs
 -remove_attribute(key)     |   removes entry, for event attrs
 -remove_attribute(key,type)    |   removes entry, specifically for event or calendar attrs
 -generate_content()        |   generates .ics syntax
 -generate()            |   writes content to .ics file

 \* *********************************************************** */
public class FileMaker {
    private LinkedHashMap<String, String> event_attributes;
    private LinkedHashMap<String, String> calendar_attributes;

    public FileMaker() {
        event_attributes = new LinkedHashMap<String, String>();
        calendar_attributes = new LinkedHashMap<String, String>();
    }

    public int set_attribute(String key, String value) {
        return set_attribute(key, value, "event");
    }

    public int set_attribute(String key, String value, String type) {
        if (type.equals("event")) {
            event_attributes.put(key, value);
        } else if (type.equals("calendar")) {
            calendar_attributes.put(key, value);
        }
        return 0;
    }

    public int remove_attribute(String key) {
        return remove_attribute(key, "event");
    }

    public int remove_attribute(String key, String type) {
        if (type.equals("event")) {
            if (event_attributes.containsKey(key)) {
                event_attributes.remove(key);
                return 1;
            }
        } else if (type.equals("calendar")) {
            if (calendar_attributes.containsKey(key)) {
                calendar_attributes.remove(key);
                return 1;
            }
        }
        return 0;
    }

    public String generate_content() {
        String content = "";
        String tags_calendar_header = "BEGIN:VCALENDAR\r\n";
        String tags_event_header = "BEGIN:VEVENT\r\n";
        String tags_footer = "END:VEVENT\r\nEND:VCALENDAR";
        
        content += (tags_calendar_header);
        
        Set calendarSet = calendar_attributes.entrySet();
        Iterator i = calendarSet.iterator();

        while (i.hasNext()) {
            Map.Entry me = (Map.Entry)i.next();
            content += (me.getKey() + ":" + me.getValue() + "\r\n");
        }

        content += (tags_event_header);

        Set eventSet = event_attributes.entrySet();
        i = eventSet.iterator();
        
        while (i.hasNext()) {
            Map.Entry me = (Map.Entry)i.next();
            content += (me.getKey() + ":" + me.getValue() + "\r\n");
        }

        content += (tags_footer);
        return content;
    }
    public boolean check_fields(){
        Set eventSet = event_attributes.entrySet();
        Iterator i = eventSet.iterator();
        
        while (i.hasNext()) {
            Map.Entry me = (Map.Entry)i.next();
            if(me.getKey().equals("")||me.getValue().equals(""))
                return false;
        }
        return true;
    }
    public boolean generate(String fileName) {
        Writer writer = null;
        if(!check_fields())
            return false;
        try {
            writer = new BufferedWriter(new OutputStreamWriter(
                    new FileOutputStream(new File(fileName + ".ics"))));
            writer.write(generate_content());
            writer.close();
            return true;
        } catch (IOException ex) {
            // report
            System.out.print(ex + "fail");
            return false;
        }

    }

}
